﻿using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AgentSystem.AgentCreator.Sbpel.Activities
{
    /// <summary>
    /// Activity class for Wait command.
    /// </summary>
    public class WaitActivity : AbstractActivity
    {
        /// <value>
        /// The wait for time.
        /// </value>
        public TimeSpan WaitForTime { get; private set; }
        
        /// <value>
        /// The wait until.
        /// </value>
        public DateTime WaitUntil { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="WaitActivity"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="waitFor">The wait for.</param>
        /// <param name="waitUntil">The wait until.</param>
        public WaitActivity(AbstractActivity parent, string name, string waitFor, string waitUntil) : base(parent)
        {
            Name = name;

            //Init properties
            WaitForTime = TimeSpan.MinValue;
            WaitUntil = DateTime.MinValue;

            //Aux variables
            int waitForMilliseconds = 0;
            DateTime waitUntilDate = DateTime.MinValue;
            
            //Wait for exists and can be parsed
            if(!string.IsNullOrEmpty(waitFor) && int.TryParse(waitFor, out waitForMilliseconds))
            {
                WaitForTime = new TimeSpan(0, 0, 0, 0, waitForMilliseconds);
            }

            //If wait until can be parsed
            if (!string.IsNullOrEmpty(waitUntil) && DateTime.TryParse(waitUntil, out waitUntilDate))
            {
                WaitUntil = waitUntilDate;
            }
            
        }

        /// <returns>
        /// String representing C# code
        /// </returns>
        public override CodeObject[] GetCodeDom()
        {
            int waitMilliseconds = 0;
            
            if(WaitForTime != TimeSpan.MinValue)
            {
                waitMilliseconds = (int)WaitForTime.TotalMilliseconds;
            }
            
            if(WaitUntil != DateTime.MinValue && DateTime.Now.CompareTo(WaitUntil) < 0)
            {
                waitMilliseconds = (int)Math.Round(WaitUntil.Subtract(DateTime.Now).TotalMilliseconds, 0);
            }

            CodeMethodInvokeExpression methodInvokeExpression = new CodeMethodInvokeExpression(
                new CodeTypeReferenceExpression("System.Threading.Thread"),
                "Sleep",
                new CodePrimitiveExpression(waitMilliseconds));

            return new CodeObject[] { methodInvokeExpression };
        }
    }
}
